package Data_Flow;

import Data_Structure.DataImplement.*;
import Data_Structure.DataType.CreditCardAccount;
import Data_Structure.DataType.MyFlight;
import Data_Structure.DataType.TargetFlight;
import Data_Structure.DataType.Traveller;
import GUI_Data.FlightSeatPanel.SeatButton;
import lombok.Data;
import org.junit.Test;

import java.io.IOException;
import java.util.*;

/**
 * Static method for GUI layer to get data of users or flights
 *
 * @author Xin Wang
 * @version 3.0
 * @since 4/17 2022
 */
@Data
public class GetData {
    //Log in method 1 need user
    private String bookingNumber;
    private String PersonID;

    private boolean ifSuccess=false;
    private boolean ifSuccessStaff = true;
    private Traveller traveller;
    private MyFlight myFlight;
    private TargetFlight targetFlight;
    private CreditCardAccount creditCardAccount;
    private HashMap<String, MyFlight> PersonFlightList;
    private List<Traveller> travellerList;
    private String[][] TravellerData;

    /**
     * Constructor.
     * Construct GetData by bookingNumber
     */
    public GetData(String bookingNumber){
        this.bookingNumber=bookingNumber;
        try{
            this.traveller=DataExplorer.readTraveller_bookingNumber(getBookingNumber());
            this.myFlight =DataExplorer.readMyFlight(getBookingNumber());
            if(traveller!=null && myFlight!=null ){
                this.targetFlight=DataExplorer.readTargetFlight(myFlight.getMyFlightID());
                this.creditCardAccount=DataExplorer.readCreditCardAccount(traveller.getPersonID());
                if (targetFlight!=null && creditCardAccount!=null)
                this.ifSuccess=true;
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Constructor.
     * Construct GetData by PersonID
     */
    public GetData(String PersonID, String SurName){
        this.PersonID=PersonID;
        try{
            this.traveller=DataExplorer.readTraveller_PersonID(getPersonID());
            if(traveller!=null && Objects.equals(traveller.getSurname(), SurName)){
                this.PersonFlightList = traveller.getFlight();
                this.creditCardAccount=DataExplorer.readCreditCardAccount(traveller.getPersonID());
                if(creditCardAccount!=null && PersonFlightList!=null) {
                    ifSuccess = true;
                }
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * User need to choose which fight it want to operate if it booked more than one flight.
     * @param FlightNumber of the flight it wants to operate.
     */
    public void ChooseFlightByFlightID(String FlightNumber){
        this.ifSuccess=false;
        try{
            this.myFlight=DataExplorer.readMyFlight(PersonFlightList.get(FlightNumber).getMyBookingNumber());
            if(myFlight!=null ){
                this.targetFlight=DataExplorer.readTargetFlight(myFlight.getMyFlightID());
                if (targetFlight!=null)
                    this.ifSuccess=true;
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    public GetData(String flightID, int antValue){

        try {
            travellerList = DataExplorer.readTraveller_staff(flightID);
            if(travellerList.size()==0)
                ifSuccessStaff = false;
            TravellerData = new String[travellerList.size()][3];
            for (int i=0; i< travellerList.size(); i++){
                TravellerData[i][0]=travellerList.get(i).getFullName();
                TravellerData[i][1]=travellerList.get(i).getPersonID();
                for (int j=0; j<travellerList.get(i).getFlight().size(); j++){
                    String index="flight"+String.valueOf(j+1);
                    if(Objects.equals(travellerList.get(i).getFlight().get(index).getMyFlightID(), flightID)){
                        if(Objects.equals(travellerList.get(i).getFlight().get(index).getMySeatPosition(),"")){
                            TravellerData[i][2] = "Yet";
                        }
                        else TravellerData[i][2] = "Done";
                    }
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    /**
     * Get ID of the user
     *
     * @return ID of the user
     */
    public String getID() {return traveller.getPersonID();}

    /**
     * Get full name of the user
     *
     * @return full name
     */
    public String getFullName() {
        return traveller.getFullName();
    }

    /**
     * Get surname of the user
     * @return surname
     */
    public String getSurName(){
        return traveller.getSurname();
    }

    /**
     * Get first name of the user
     * @return firstname
     */
    public String getFirstName(){
        return traveller.getFirstname();
    }

    /**
     * Get gender of the user
     * @return gender
     */
    public Gender.GenderE getGender(){
        return traveller.getGender();
    }

    /**
     * Get Carry on baggages of the user
     * @return MyCarryOnBaggage
     */
    public int getMyCarryOnBaggage(){return myFlight.getMyCarryOnBaggage();}

    /**
     * Get check in baggage of the user
     * @return MyCheckInBaggage
     */
    public int getMyCheckInBaggage(){return myFlight.getMyCheckInBaggage();}

    /**
     * Get take off time of the user's flight
     * @return MyTakeOffTime
     */
    public Date getMyTakeOffTime(){return myFlight.getMyTakeOffTime();}

    /**
     * Get landing time of the user's flight
     * @return MyLandingTime
     */
    public Date getMyLandingTime(){return myFlight.getMyLandingTime();}

    /**
     * Get boarding time of the user's flight
     * @return BoardingTime
     */
    public Date getMyBoardingTime(){return myFlight.getMyBoardingTime();}

    /**
     * Get Start Point of the user
     * @return MyStartPoint
     */
    public String getMyStartPoint(){return myFlight.getMyStartPoint();}

    /**
     * Get Dest Point of the user
     * @return MyDestPoint
     */
    public String getMyDestPoint(){return myFlight.getMyDestPoint();}

    /**
     * Get FlightID of the user
     * @return MyFlightID
     */
    public String getMyFlightID(){return myFlight.getMyFlightID();}

    /**
     * Get Gate of the user
     * @return MyGate
     */
    public String getMyGate(){return myFlight.getMyGate();}

    /**
     * Get Plane Type of the user's flight
     * @return MyPlaneType
     */
    public Flight.PlaneType getMyPlaneType(){return myFlight.getMyPlaneType();}

    /**
     * Get Flight Status of the user's flight
     * @return MyFlightStatus
     */
    public FlightStatus.FlightStatusFs getMyFlightStatus(){return myFlight.getFlightStatus();}

    /**
     * Get Seat class of the user's seat.
     * @return SeatClass
     */
    public String getMySeatClass(){
        return myFlight.getMySeatClass();
    }

    /**
     * Get seat position of the user.
     * @return seatPosition
     */
    public String getMySeatPosition(){
        return myFlight.getMySeatPosition();
    }

    /**
     * Get seat price of the user's seat.
     * @return seatPrice
     */
    public int getMySeatPrice() {
        return myFlight.getMySeatPrice();
    }

    /**
     * Get booking number of the user.
     * @return bookingNumber
     */
    public String getMyBookingNumber(){return myFlight.getMyBookingNumber();}

    /**
     * Get meals and their number of the user.
     * @return HashMap<MealAndPrice.Meals, Integer>
     */
    public HashMap<MealAndPrice.Meals, Integer> getMyMeals(){return myFlight.getMeals();}

    /**
     * Get meals and their price of the user.
     * @return HashMap<MealAndPrice.Meals, Integer>
     */
    public  HashMap<MealAndPrice.Meals, Integer> getMyMealPrice(){return myFlight.getMealPrice();}

    /**
     *Check is the seat selected, and return a boolean value. true means selected, false means not yet.
     * @return a boolean value
     */
    public boolean ifSeatSelectable(SeatButton seatButton){
        HashMap<String, Boolean> targetSeatPosition = targetFlight.getTargetSeatClass().get(seatButton.getSeatClass());
        return targetSeatPosition.get(seatButton.getSeatPosition());
    }


    public HashMap<String, HashMap<String, Boolean>> getTargetSeatClass(SeatButton seatButton){
        return targetFlight.getTargetSeatClass();
    }

    /**
     * To get the number of kinds of meals
     * @return the number of kinds of meals
     */
    public ArrayList<HashMap<MealAndPrice.Meals,Integer>> getMealServerNumber(){
        return targetFlight.getTargetMealAndPrice();
    }

    /**
     * Get seat price of all kind of seats.
     *
     * @return seat price
     */
    public static int getSeatPrice(Flight.PlaneType planeType, String seatClass){
        switch (planeType) {
            case Boeing737 -> {
                if (seatClass.equals(SeatClassAndPrice.Boeing737SeatClass[0]))
                    return SeatClassAndPrice.Boeing737SeatClassAPrice;
                else if (seatClass.equals(SeatClassAndPrice.Boeing737SeatClass[1]))
                    return SeatClassAndPrice.Boeing737SeatClassBPrice;
                else if (seatClass.equals(SeatClassAndPrice.Boeing737SeatClass[2]))
                    return SeatClassAndPrice.Boeing737SeatClassCPrice;
            }
            case AirbusA320 -> {
                if (seatClass.equals(SeatClassAndPrice.AirbusA320SeatClass[0]))
                    return SeatClassAndPrice.AirbusA320SeatClassAPrice;
                else if (seatClass.equals(SeatClassAndPrice.AirbusA320SeatClass[1]))
                    return SeatClassAndPrice.AirbusA320SeatClassBPrice;
            }
        }
        return -1;
    }

    /**
     * Get Credit card ID.
     * @return Credit card ID.
     */
    public String getCreditCardID(){return creditCardAccount.getCardID();}

    /**
     * Get credit card balance.
     * @return Balance.
     */
    public double getBalance(){return creditCardAccount.getBalance();}

    /**
     * Get overdraft limit.
     * @return Overdraft limit.
     */
    public double getOverdraftLimit(){return creditCardAccount.getOverdraftLimit();}




}

